package com.ibpd.henuocms.tlds;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.Tag;

import org.h2.util.StringUtils;
import org.hsqldb.lib.StringUtil;

import com.ibpd.dao.impl.ServiceProxyFactory;
import com.ibpd.henuocms.common.IbpdCommon;
import com.ibpd.henuocms.common.IbpdLogger;
import com.ibpd.henuocms.common.TimeHelper;
import com.ibpd.henuocms.entity.NodeAttrEntity;
import com.ibpd.henuocms.entity.NodeEntity;
import com.ibpd.henuocms.entity.SubSiteEntity;
import com.ibpd.henuocms.entity.ext.NodeExtEntity;
import com.ibpd.henuocms.service.content.ContentServiceImpl;
import com.ibpd.henuocms.service.content.IContentService;
import com.ibpd.henuocms.service.node.INodeService;
import com.ibpd.henuocms.service.node.NodeServiceImpl;
import com.ibpd.henuocms.service.nodeAttr.INodeAttrService;
import com.ibpd.henuocms.service.nodeAttr.NodeAttrServiceImpl;
import com.ibpd.henuocms.service.subSite.ISubSiteService;
import com.ibpd.henuocms.service.subSite.SubSiteServiceImpl;
import com.ibpd.henuocms.web.controller.web.WebSite;

public class NodeTag extends SimpleBaseTag {
	private String nodeId="";
	private Object value;
	private String valueVar="";
	private String field="";
	public void setField(String field) {
		this.field = field;
	}

	private String dateFormat=""; 
	private String escape="";
	private NodeExtEntity node=null;
	public String getField() {
		return field;
	}

	@Override
	public void doTag() throws JspException, IOException {
		_init();
		if(node==null){
            return ;
            }
	        getJspContext().getOut().write(getFieldValue(node,field));
	        if(getJspBody()!=null)
	        	getJspBody().invoke(null);
	}

	private String getFieldValue(NodeExtEntity nodeExtEntity,String fieldName){
		String rtn="";
		if(nodeExtEntity==null)
			return "";
		Object obj=nodeExtEntity.getNode();
		if(obj==null)
			return "";
		else{
			try{
				String getFunName="get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
//				Method funMethod=obj.getClass().getMethod(getFunName, new Class[]{});
				if(!existMethod(getFunName,obj)){
					NodeAttrEntity attr=nodeExtEntity.getAttr();
					if(attr==null)
						return "";
					else{
						if(!existMethod(getFunName,attr)){
							//如果在node和attr中都没有该属性，那么就有可能是前台让返回url目录或者字段信息错误
							HttpServletRequest request= getRequest();
							if(nodeExtEntity.getNodeType()==NodeEntity.NODETYPE_REDIRECT){
								return nodeExtEntity.getLinkUrl();
							}else if(fieldName.toUpperCase().trim().equals("FULLURL")){
								String path = request.getContextPath();
								String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
								String dir=getNodeUrlDir(nodeExtEntity.getNode(),request);
								return basePath+dir;
							}else if(fieldName.toUpperCase().trim().equals("SHORTURL")){
								String path = request.getContextPath()+"/";
								if(!checkViewerMode()){
									path="/";
								}
								String dir=getNodeUrlDir(nodeExtEntity.getNode(),request);
	 							return path+dir;
							}else{
								return "field设置错误";
							}
						}else{
							Method funMethod=attr.getClass().getMethod(getFunName, new Class[]{});
							rtn=getReturnValue(funMethod,attr);
						}
					}
				}else{
					Method funMethod=obj.getClass().getMethod(getFunName, new Class[]{});
					rtn=getReturnValue(funMethod,obj);
				}
			}catch(Exception e){
				e.printStackTrace();
				return "";
			}
		}
		if(!checkViewerMode()){
			Long siteId=nodeExtEntity.getSubSiteId();
			ISubSiteService siteServ=(ISubSiteService) ServiceProxyFactory.getServiceProxy(SubSiteServiceImpl.class);
			SubSiteEntity s=siteServ.getEntityById(siteId);
			if(s!=null)
				rtn=rtn.replace("/sites/"+s.getDirectory(), "");
		}
		return rtn;
	}
	private Boolean existMethod(String mtName,Object obj){
		Method[] mts=obj.getClass().getMethods();
		for(Method mt:mts){
			if(mt.getName().equals(mtName)){
				return true;
			}
		}
		return false;
	}
	private String getNodeUrlDir(NodeEntity node,HttpServletRequest req){
		if(node==null)
			return "";
		ISubSiteService siteServ=(ISubSiteService) ServiceProxyFactory.getServiceProxy(SubSiteServiceImpl.class);
		SubSiteEntity site=siteServ.getEntityById(node.getSubSiteId());
		String idPath=node.getNodeIdPath();
		String[] ids=idPath.split(",");
		Map<Long,String> dirMap=new LinkedHashMap<Long,String>();
		//先把要取的目录都取出来
		INodeAttrService attrService=(INodeAttrService) ServiceProxyFactory.getServiceProxy(NodeAttrServiceImpl.class);
		for(String id:ids){
			if(StringUtil.isEmpty(id))
				continue;
			if(StringUtils.isNumber(id)){
				Long nodeId=Long.parseLong(id);
				NodeAttrEntity attr=attrService.getNodeAttr(nodeId);
				if(attr!=null){
					dirMap.put(nodeId, attr.getDirectory());//理论上这里取出来的目录顺序是正确的，这里之所以要把目录放入跟ID对照的map中，是为了以后扩展方便
				}
			}
			
		}  
		String dir="";  
		if(site!=null){ 
			String type=req.getParameter("type"); 
			if(!StringUtils.isNullOrEmpty(type) && type.trim().toLowerCase().equals(WebSite.WEBPAGE_TYPE_VIEWER.toString())){
				dir="sites/"+site.getDirectory()+"/";
			} 
		}
		for(Long key:dirMap.keySet()){
			dir+=dirMap.get(key)+"/"; 
		}
		dir=dir+"index.html";
		return dir;
	}
	private String getReturnValue(Method mthod,Object obj) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
		Object rtn=mthod.invoke(obj, null);
		if(mthod.getReturnType().getSimpleName().equals("Date")){
			if(!StringUtil.isEmpty(dateFormat)){
				return TimeHelper.getDate((Date)rtn, dateFormat);
			}else{
				return escapeValue(rtn.toString(),this.getEscape());
			}
		}
		return escapeValue(rtn.toString(),this.getEscape());
		
	}


	protected void _init() {
		if(!StringUtils.isNullOrEmpty(valueVar)){
			Object o=getJspContext().getAttribute(valueVar);
			if(o==null){
				node=null;
			}else{
				node=(NodeExtEntity) o;
			}
		}else if(value!=null){
			node=(NodeExtEntity) value;
		}else if(!StringUtils.isNullOrEmpty(nodeId)){
			if(nodeId.toUpperCase().trim().equals("OWNER")){
				nodeId=getRequest().getParameter("nodeId");
			}else if(StringUtils.isNumber(nodeId)){
				 
			}else{
				nodeId="-1";
			}
			Long currentNodeId=Long.valueOf(nodeId);
			if(!currentNodeId.equals(-1L)){
				INodeService nodeServ=(INodeService) ServiceProxyFactory.getServiceProxy(NodeServiceImpl.class);
				NodeEntity n=nodeServ.getEntityById(currentNodeId);
				NodeExtEntity ext=new NodeExtEntity();
				ext.setNode(n);
				INodeAttrService attrServ=(INodeAttrService) ServiceProxyFactory.getServiceProxy(NodeAttrServiceImpl.class);
				NodeAttrEntity attr=attrServ.getNodeAttr(currentNodeId);
				ext.setAttr(attr);
				node=ext;
			}
		}else{
			node=null;
		}
	}

	public void setDateFormat(String dateFormat) {
		this.dateFormat = dateFormat;
	}

	public String getDateFormat() {
		return dateFormat;
	}

	public void setEscape(String escape) {
		this.escape = escape;
	}

	public String getEscape() {
		return escape;
	}

	public void setNodeId(String nodeId) {
		this.nodeId = nodeId;
	}

	public String getNodeId() {
		return nodeId;
	}

	public void setValueVar(String valueVar) {
		this.valueVar = valueVar;
	}

	public String getValueVar() {
		return valueVar;
	}

	public void setValue(Object value) {
		this.value = value;
	}

	public Object getValue() {
		return value;
	}

}